package instrumenter;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import cfg.mpsc.INode;

public class ExecutedNode implements INode{

	private enum NODETYPE {PRE, POST};
	@XmlElement
	public Integer bytecode;
	@XmlElement
	public NODETYPE executionType;


	/** next nodes list */
	private List<INode> nextNodes = new ArrayList<INode>();

	@Override
	public List<INode> nextNodes() {
		return nextNodes;
	}
	@Override
	public void setBytecodeNumber(int n) {
		this.bytecode=n;
	}
	@Override
	public int getBytecodenumber() {
		return bytecode;
	}


	
	public String toString(){
		return "["+bytecode+"]";
	}


	public static INode processList(String fileName){
		try {
			File file = new File(fileName);
			//add <list> ...content... </list> to file
			file = prepareFile(file);

			JAXBContext jaxbContext = JAXBContext.newInstance(NodeList.class);

			Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
			NodeList	 nodes = (NodeList) jaxbUnmarshaller.unmarshal(file);

			List<INode> list = process(nodes.list);
			return list.get(0);
		} catch (JAXBException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}


	private static File prepareFile(File file) throws IOException {
		BufferedReader reader = new BufferedReader(new FileReader(file));
		BufferedWriter writer = new BufferedWriter(new FileWriter(new File(file.getAbsolutePath()+".list")));
		writer.write("<list>");		
		while(reader.ready()){
			writer.write(reader.readLine());
		}
		writer.write("</list>");
		writer.close();
		reader.close();
		return new File(file.getAbsolutePath()+".list");
	}



	private static List<INode> process(List<ExecutedNode> list2) {
		List<INode> list = new ArrayList<INode>();

		ExecutedNode atual = list2.get(0);
		ExecutedNode ant=null;

		list.add(atual);
		for(int i=1;i<list2.size();++i){
			ant = atual;
			atual = list2.get(i);
			System.out.println("Analizando bytecode: "+atual.getBytecodenumber());
			if(ant.bytecode==atual.bytecode && ant.executionType == NODETYPE.PRE && atual.executionType == NODETYPE.POST){
				//ignore
				System.out.println("\t ignorando...");
			} else {
				System.out.println("\t adicionando...");
				list.get(list.size()-1).nextNodes().add(atual);
				list.add(atual);
			}
		}
		for(int i=1;i<list.size();++i){
			list.get(i-1).nextNodes().add(list.get(i));
		}
		return list;
	}

	@XmlRootElement(name="list")
	public static class NodeList{
		@XmlElement(name="node")
		public ArrayList<ExecutedNode> list;
	}
/*	
<<<<<<< .mine
	
	public static void main(String[] args) throws IOException {
		String execCommand = "java.exe -noverify -cp .tempExecution model.Main";
		System.out.println(execCommand);
		Process p = Runtime.getRuntime().exec(execCommand);
		
		
		
		
		
		BufferedReader stdInput = new BufferedReader(new 
                InputStreamReader(p.getInputStream()));

           BufferedReader stdError = new BufferedReader(new 
                InputStreamReader(p.getErrorStream()));

           // read the output from the command
           System.out.println("Here is the standard output of the command:\n");
           String s;
           while ((s = stdInput.readLine()) != null) {
               System.out.println(s);
           }
           
           // read any errors from the attempted command
           System.out.println("Here is the standard error of the command (if any):\n");
           while ((s = stdError.readLine()) != null) {
               System.out.println(s);
           }
		
		String file = ".tempExecution\\trace.log";
		INode start = ExecutedNode.processList(file);
		while(start!=null){
			System.out.println(start.getBytecodenumber());
			if(!start.nextNodes().isEmpty()){
				start = start.nextNodes().get(0);
			} else {
				start = null;
			}
		}
	}
=======

>>>>>>> .r28

	*/
	
}
